﻿// ===============================================================================
// NotEmpty.cs
// EOS Framework
// ===============================================================================
// Copyright (c) EOS Development Group. All rights reserved.
// ===============================================================================

namespace EOS.Framework.Tools.Aspects
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Reflection;
    using PostSharp.Laos;

    /// <summary>
    /// Aspect for verifying, that a value passed to a property
    /// is not empty. Can only assigned to attributes.
    /// </summary>
    [Serializable]
    [AttributeUsage(AttributeTargets.Property)]
    public sealed class NotEmpty : OnMethodBoundaryAspect
    {
        /// <summary>
        /// Method executed <b>before</b> the body of methods to which this aspect is applied. If the property type
        /// is a string, the method secures that the passed string value is not empty or has only blanks.
        /// </summary>
        /// <param name="eventArgs">Event arguments specifying which method
        /// is being executed, which are its arguments, and how should the execution continue
        /// after the execution of <see cref="M:PostSharp.Laos.IOnMethodBoundaryAspect.OnEntry(PostSharp.Laos.MethodExecutionEventArgs)"/>.</param>
        /// <remarks>
        /// If the aspect is applied to a constructor, the current method is invoked
        /// after the <b>this</b> pointer has been initialized, that is, after
        /// the base constructor has been called.
        /// </remarks>
        /// <exception cref="ArgumentException"><paramref name="value"/> is a string
        /// and is empty or has only blanks.</exception>
        [SuppressMessage("Microsoft.Usage", "CA2208")]
        public override void OnEntry(MethodExecutionEventArgs eventArgs)
        {
            ParameterInfo[] pinfo = eventArgs.Method.GetParameters();
            if (pinfo.Length == 1)
            {
                object value = eventArgs.GetReadOnlyArgumentArray()[0];

                string valueAsString = value as string;
                if (valueAsString != null && StringHelper.IsEmptyOrBlanksOnly(valueAsString))
                {
                    throw new ArgumentException(
                        "String parameter cannot be empty and cannot contain only blanks", "value");
                }
            }
            base.OnEntry(eventArgs);
        }
    }
}
